import os
from threading import Lock


class FifoBase:
    _instance_lock = Lock()

    def __init__(self, base_path):
        self.fifo_dir = base_path if base_path.endswith("/") else base_path + "/"
        self.read_path = self.fifo_dir + "read.fi"
        self.write_path = self.fifo_dir + "read.fo"
        if os.path.exists(self.read_path):
            os.remove(self.read_path)
        if os.path.exists(self.write_path):
            os.remove(self.write_path)
        os.mkfifo(self.write_path)
        os.mkfifo(self.read_path)
        self.rf = os.open(self.read_path, os.O_RDONLY)
        self.wf = os.open(self.write_path, os.O_SYNC | os.O_CREAT | os.O_RDWR)

    def write(self, val):
        self.wf.write(val + os.linesep)

    def read(self):
        self.rf.readline()

    def close(self):
        os.close(self.rf)
        os.close(self.wf)

    @staticmethod
    def init(base_path):
        with FifoBase._instance_lock:
            if not hasattr(FifoBase, "_instance"):
                FifoBase._instance = FifoBase(base_path=base_path)

    @staticmethod
    def instance():
        if hasattr(FifoBase, "_instance"):
            return getattr(FifoBase, "_instance")
        return None

